#!/usr/bin/env python
# encoding: utf-8
"""
semrep_mesh.py

Reads a SEMREP file and output MeSH terms instead of UMLS concepts.
It will ignore text lines, but convert terms in the Relationships properly (you never know...)

Created by Jorge Herskovic on 2008-09-09.
Copyright (c) 2008 University of Texas - Houston. All rights reserved.
"""

from MEDRank.file.semrep import (SemrepOutput, 
                                 EntityLine,
                                 RelationLine, 
                                 TextLine,
                                 DEFAULT_LINES_TO_IGNORE)
from MEDRank.file.nlm_output import NoLineTypeError, UnknownLineTypeError
                                 
from MEDRank.umls.concept import Concept

class EntityMeSHLine(EntityLine):
    """Augments an EntityLine with a converted MeSH Expression."""
    __slots__=['_mesh']
    def __init__(self, original_line, converter):
        EntityLine.__init__(self, original_line)
        self._mesh=converter.convert(Concept(self.CUI))
        dummy=converter.end_conversion()    # Discard extra terms generated by 
                                            # the converter
    def get_mesh(self):                 
        return self._mesh
    mesh=property(get_mesh)

class RelationMeSHLine(RelationLine):
    __slots__=['_mesh1', '_mesh2']
    def __init__(self, original_line, converter):
        RelationLine.__init__(self, original_line)
        self._mesh1=converter.convert(Concept(self.CUI1))
        self._mesh2=converter.convert(Concept(self.CUI2))
        dummy=converter.end_conversion()    # Discard extra terms generated by
                                            # the converter
    def get_mesh1(self):
        return self._mesh1
    mesh1=property(get_mesh1)
    def get_mesh2(self):
        return self._mesh2
    mesh2=property(get_mesh2)

class SemrepMeSHOutput(SemrepOutput):
    """Reads a Semrep Output file, outputs MeSH terms instead of UMLS 
    concepts. Keeps the CUIs for backwards compatibility."""
    def __init__(self, fileobject, lines_to_ignore, chunkmap, converter):
        SemrepOutput.__init__(self, fileobject,
                              lines_to_ignore=lines_to_ignore,
                              chunkmap=chunkmap)
        self._my_converter=converter
        self.line_type=self.line_factory
    def line_factory(self, line_text):
        try:
            line_type=line_text.split('|')[5]
        except IndexError:
            raise NoLineTypeError("Could not determine the line type of '%s'",
                                  line_text)
        if line_type=='entity':
            return EntityMeSHLine(line_text, self._my_converter)
        if line_type=="relation":
            return RelationMeSHLine(line_text, self._my_converter)
        if line_type=='text':
            return TextLine(line_text)
        raise UnknownLineTypeError("Unknown line type in line '%s'", line_text)

        